package streaming.test.call;

import java.awt.Component;
import java.net.InetAddress;

import javax.media.CaptureDeviceInfo;
import javax.media.ConfigureCompleteEvent;
import javax.media.ControllerEvent;
import javax.media.ControllerListener;
import javax.media.Format;
import javax.media.Manager;
import javax.media.Player;
import javax.media.Processor;
import javax.media.ProcessorModel;
import javax.media.RealizeCompleteEvent;
import javax.media.control.TrackControl;
import javax.media.format.AudioFormat;
import javax.media.format.UnsupportedFormatException;
import javax.media.format.VideoFormat;
import javax.media.protocol.ContentDescriptor;
import javax.media.protocol.DataSource;
import javax.media.protocol.PushBufferDataSource;
import javax.media.protocol.PushBufferStream;
import javax.media.protocol.SourceCloneable;
import javax.media.rtp.RTPManager;
import javax.media.rtp.SendStream;
import javax.media.rtp.SessionAddress;
import javax.swing.JFrame;

public class RTPTransmiter extends JFrame implements ControllerListener{

	
	private Processor capturingProcessor;
	private Processor sendingProcessor;
	private Player player;
	private CaptureDeviceInfo choosenDevice;
	
	
	private AudioFormat rtpAudioFormat = new AudioFormat(AudioFormat.GSM_RTP);
	private VideoFormat rtpVideoFormat = new VideoFormat(VideoFormat.H263_RTP);
	
	private ContentDescriptor processorDesc = new ContentDescriptor(ContentDescriptor.RAW);
	private ContentDescriptor rtpDesc = new ContentDescriptor(ContentDescriptor.RAW_RTP);
	
	private AudioFormat audioFormat = new AudioFormat(AudioFormat.LINEAR, 8000, 8, 1);
	private VideoFormat videoFormat = new VideoFormat(VideoFormat.H263);
	
	public RTPTransmiter() throws Exception{
//		Vector<CaptureDeviceInfo> devices = CaptureDeviceManager.getDeviceList(format);
//		
//		if(!devices.isEmpty()){
//			choosenDevice = devices.get(1);
//			System.out.println("Selected device is: "  + choosenDevice);
//		}
//		else throw new Exception("No devices that support DVI audio format");
//	
		initializeCapturer();
		
	}
	
	private synchronized void initializeCapturer() throws Exception{
//		MediaLocator ml = choosenDevice.getLocator();
//		
//		capturingProcessor = Manager.createProcessor(ml);
		capturingProcessor = Manager.createRealizedProcessor(new ProcessorModel(new Format[]{audioFormat, videoFormat}, processorDesc));
		
		capturingProcessor.addControllerListener(this);
//		capturingProcessor.configure();
//		wait();
//		
//		capturingProcessor.realize();
//		wait();
		
		
		DataSource origData = capturingProcessor.getDataOutput();
		
		DataSource cloneableData = Manager.createCloneableDataSource(origData);
		DataSource clonedData = ((SourceCloneable)cloneableData).createClone();
		
		player = Manager.createRealizedPlayer(origData);
		
		clonedData.connect();
		
		sendingProcessor = Manager.createProcessor(clonedData);
		sendingProcessor.addControllerListener(this);
		sendingProcessor.configure();
		wait();
		
		
		sendingProcessor.setContentDescriptor(rtpDesc);
		TrackControl[] tracks = sendingProcessor.getTrackControls();
		
		Format[] supported;
		for(TrackControl track : tracks){
			supported = track.getSupportedFormats();
//			if(track.getFormat() instanceof AudioFormat){
				track.setFormat(supported[0]);
//			}
//			else{
//				track.setFormat(rtpVideoFormat);
//			}
		}
		
		sendingProcessor.realize();
		wait();
		
		
		PushBufferDataSource pds = (PushBufferDataSource)sendingProcessor.getDataOutput();
		PushBufferStream pss[] = pds.getStreams();
		System.out.println(pss.length);
		RTPManager[] managers = new RTPManager[pss.length];
		
		InetAddress address = InetAddress.getByName("192.168.1.255");
		int port = 22222;
		SessionAddress local, dest;
		SendStream sendStream;
		for(int i = 0; i < managers.length; i++){
			
			managers[i] = RTPManager.newInstance();
			local = new SessionAddress(InetAddress.getLocalHost(), port+2*i, 1);
			dest = new SessionAddress(address, port+2*i, 1);
			managers[i].initialize(local);
			managers[i].addTarget(dest);
			sendStream = managers[i].createSendStream(sendingProcessor.getDataOutput(), i);
			sendStream.start();
			System.out.println("Started stream:rtp://" + local.getDataHostAddress() + ":" + local.getDataPort() + "/" + sendStream.getDataSource().getContentType()+"/" + local.getTimeToLive());
		}
		capturingProcessor.start();
		player.start();
		
		
		
		
		
		if(player != null){
			Component visual = player.getVisualComponent();
			if(visual != null){
				setBounds(0, 0, 480, 360);
				getContentPane().add(visual);
				setVisible(true);
			}
		}
		
//		capturingProcessor.start();
		
//		DataSink sink = Manager.createDataSink(capturingProcessor.getDataOutput(), new MediaLocator("FILE:///c:/test.vaw"));
//		sink.open();
//		sink.start();
	}
	
	
	@Override
	public synchronized void controllerUpdate(ControllerEvent e) {
		
		if(e instanceof ConfigureCompleteEvent){
			System.out.println("configured");
			if(e.getSource().equals(sendingProcessor))
			notifyAll();
		}
		
		else if (e instanceof RealizeCompleteEvent){
			System.out.println("realized");
			if(e.getSource().equals(sendingProcessor))
			notifyAll();
		}
		
	}
	
	public static void main(String[] args) {
		try {
			new RTPTransmiter();
		
		
		} catch (UnsupportedFormatException e) {
			// TODO Auto-generated catch block
			System.out.println("failed:"  + e.getFailedFormat());
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
